<template>
  <div class="calendar" ref="calendar">
    <CalendarHead />
    <div class="calendar-body">
      <component :is="componentName" />
    </div>
    <div
      class="mask"
      :style="{transform: `translate(${translateX}px, ${translateY}px)`, background: `${isEnter ? 'radial-gradient(transparent, #444 70px, #444)' : '#444'}`}"
    ></div>
  </div>
</template>

<script>
import CalendarHead from './children/CalendarHead'
import DayPanel from './children/DayPanel'
import MonthPanel from './children/MonthPanel'
import dayjs from 'dayjs'
import { ref, reactive, onMounted, toRefs, onUnmounted, provide } from 'vue'
export default {
  name: 'calendarWrapper',
  components: {
    CalendarHead,
    DayPanel,
    MonthPanel
  },
  setup() {
    const calendar = ref(null)
    const state = reactive({
      translateX: 0,
      translateY: 0,
      maskWidth: 0,
      maskHeight: 0,
      isEnter: false,
    })
    let rect = {}
    const onMouseEnter = () => {
      state.isEnter = true
      rect = calendar.value.getBoundingClientRect()
      state.maskWidth = rect.width
      state.maskHeight = rect.height
    }
    const onMouseMove = (e) => {
      if (state.isEnter) {
        const { clientX, clientY } = e
        const { maskWidth, maskHeight } = state
        state.translateX = clientX - rect.left - maskWidth
        state.translateY = clientY - rect.top - maskHeight
      }
    }
    const onMouseLeave = () => {
      state.isEnter = false
    }
    onMounted(() => {
      calendar.value.addEventListener('mouseenter', onMouseEnter)
      calendar.value.addEventListener('mousemove', onMouseMove)
      calendar.value.addEventListener('mouseleave', onMouseLeave)
    })
    onUnmounted(() => {
      calendar.value.removeEventListener('mouseenter', onMouseEnter)
      calendar.value.removeEventListener('mousemove', onMouseMove)
      calendar.value.removeEventListener('mouseleave', onMouseLeave)
    })
    const currentDate = ref(dayjs())
    const setDate = (date) => {
      currentDate.value = date
    }
    provide('currentDate', currentDate)
    provide('setDate', setDate)
    const currentMode = ref('day')
    const componentName = ref('DayPanel')
    const setMode = (mode) => {
      switch(mode) {
        case 'day':
          currentMode.value = 'day'
          componentName.value = 'DayPanel'
          break
        case 'month':
          currentMode.value = 'month'
          componentName.value = 'MonthPanel'
          break
      }
    }
    provide('currentMode', currentMode)
    provide('setMode', setMode)
    return {
      calendar,
      ...toRefs(state),
      componentName
    }
  }
}
</script>

<style lang="less" scoped>
.calendar {
  width: 350px;
  height: 370px;
  background-color: #444;
  color: #fff;
  padding: 20px;
  margin: auto;
  overflow: hidden;
  position: relative;
  user-select: none;
  .calendar-body {
    width: 100%;
    height: 350px;
  }
  .mask {
    width: 200%;
    height: 200%;
    background: radial-gradient(transparent, #444 60px, #444);
    // background: #444;
    position: absolute;
    top: 0;
    left: 0;
  }
}
</style>